/*
 * 
* Copyright (C) 2004-2006  Autodesk, Inc.
* 
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2.1 of the GNU Lesser
* General Public License as published by the Free Software Foundation.
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
* 
 */

#include "Pch.h"
#include "InsertTests.h"
#include "UnitTestUtility.h"

#include <FdoSpatial.h>
#include <FdoCommonFile.h>

#ifdef _WIN32
#define LOCATION L"..\\..\\TestData\\Testing"
#define SCHEMA_NAME L"\\schema.xml"
#define CPG_NAME L"\\Test.cpg"
#define DBG_NAME L"\\Test.dbf"
#else
#define LOCATION L"../../TestData/Testing"
#define SCHEMA_NAME L"/schema.xml"
#define CPG_NAME L"/Test.cpg"
#define DBG_NAME L"/Test.dbf"
#endif

#define TEST_FEATURE_CLASS L"Test"
#define TEST2_FEATURE_CLASS L"Test2"
#define TESTFDOCLASS_FEATURE_CLASS L"TestFdoClass"

CPPUNIT_TEST_SUITE_REGISTRATION (InsertTests);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION (InsertTests, "InsertTests");

FdoPtr<FdoIConnection> InsertTests::mConnection;

InsertTests::InsertTests (void)
{
    m_schemaNames = FdoStringCollection::Create();
    m_schemaNames->Add(L"TAB");
    m_schemaNames->Add(L"MIF");
}

InsertTests::~InsertTests (void)
{
}

FdoStringP InsertTests::GetQualifiedClassName(FdoString* schema, FdoString* fcName)
{
    FdoStringP qualifiedName = schema;
    qualifiedName += L":";
    qualifiedName += fcName;
    return qualifiedName;
}

void InsertTests::setUp ()
{
    if (!FdoCommonFile::FileExists (LOCATION))
        FdoCommonFile::MkDir (LOCATION);
    mConnection = MapInfoTests::GetConnection ();
    MapInfoTests::sLocation = LOCATION;
    mConnection->SetConnectionString (L"DefaultFileLocation=" LOCATION);
    CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());
}

void InsertTests::tearDown ()
{

    mConnection->Close ();

    // Reopen connection
    mConnection->Open ();

    // Delete old class, if its there:
    for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
    {
        TestCommonSchemaUtil::CleanUpClass(mConnection, m_schemaNames->GetString(i), TEST_FEATURE_CLASS);
        TestCommonSchemaUtil::CleanUpClass(mConnection, m_schemaNames->GetString(i), TEST2_FEATURE_CLASS);
        TestCommonSchemaUtil::CleanUpClass(mConnection, m_schemaNames->GetString(i), TESTFDOCLASS_FEATURE_CLASS);
    }

    mConnection->Close ();
    FDO_SAFE_RELEASE(mConnection.p);

    if (FdoCommonFile::FileExists (LOCATION SCHEMA_NAME))
        FdoCommonFile::Delete (LOCATION SCHEMA_NAME);
    if (FdoCommonFile::FileExists (LOCATION))
        FdoCommonFile::RmDir (LOCATION);
}

void InsertTests::create_schema (FdoString* schemaName, FdoGeometricType type, bool elevation, bool measure)
{
    // Delete old class, if its still there:
    TestCommonSchemaUtil::CleanUpClass(mConnection, schemaName, TEST_FEATURE_CLASS);
    TestCommonSchemaUtil::CleanUpClass(mConnection, schemaName, TEST2_FEATURE_CLASS);
    TestCommonSchemaUtil::CleanUpClass(mConnection, schemaName, TESTFDOCLASS_FEATURE_CLASS);

    // Create the FdoFeatureClass "Test":
    //////////////////////////////////////////////////////////////////////////////////////////////////

    FdoPtr<FdoDataPropertyDefinition> featid = FdoDataPropertyDefinition::Create (L"FeatId", L"integer");
    featid->SetDataType (FdoDataType_Int32);
    featid->SetIsAutoGenerated (true);
    featid->SetNullable (false);

    FdoPtr<FdoDataPropertyDefinition> id = FdoDataPropertyDefinition::Create (L"Id", L"integer");
    id->SetDataType (FdoDataType_Decimal);
    id->SetPrecision(10);
    id->SetScale(0);

    FdoPtr<FdoDataPropertyDefinition> street = FdoDataPropertyDefinition::Create (L"Street", L"text");
    street->SetDataType (FdoDataType_String);
    street->SetLength (64);

    FdoPtr<FdoDataPropertyDefinition> area = FdoDataPropertyDefinition::Create (L"Area", L"decimal");
    area->SetDataType (FdoDataType_Decimal);
    area->SetPrecision(20);
    area->SetScale(8);

    FdoPtr<FdoDataPropertyDefinition> vacant = FdoDataPropertyDefinition::Create (L"Vacant", L"boolean");
    vacant->SetDataType (FdoDataType_Boolean);

    FdoPtr<FdoDataPropertyDefinition> birthday = FdoDataPropertyDefinition::Create (L"Birthday", L"date");
    birthday->SetDataType (FdoDataType_DateTime);

    // build a location geometry property (if requested):
    FdoPtr<FdoGeometricPropertyDefinition> location;
    if (type > 0)
    {
        location = FdoGeometricPropertyDefinition::Create (L"Geometry", L"geometry");
        location->SetGeometryTypes (type);
        location->SetHasElevation (elevation);
        location->SetHasMeasure (measure);
    }

    //// assemble the feature class
    FdoPtr<FdoFeatureClass> feature = FdoFeatureClass::Create (L"Test", L"test class created with apply schema");
    FdoPtr<FdoPropertyDefinitionCollection> properties = feature->GetProperties ();
    FdoPtr<FdoDataPropertyDefinitionCollection> identities = feature->GetIdentityProperties ();
    properties->Add (featid);
    identities->Add (featid);
    properties->Add (id);
    properties->Add (street);
    properties->Add (area);
    properties->Add (vacant);
    properties->Add (birthday);
    if (location)
    {
        properties->Add (location);
        feature->SetGeometryProperty (location);
    }


    // Create the FdoFeatureClass "Test2":  (identical to "Test")
    //////////////////////////////////////////////////////////////////////////////////////////////////

    FdoPtr<FdoFeatureClass> feature2 = FdoFeatureClass::Create (L"Test2", L"test class created with apply schema");
    FdoPtr<FdoPropertyDefinitionCollection> properties2 = feature2->GetProperties ();
    FdoPtr<FdoDataPropertyDefinitionCollection> identities2 = feature2->GetIdentityProperties ();

    FdoPtr<FdoDataPropertyDefinition> featid2 = FdoDataPropertyDefinition::Create (L"FeatId", L"integer");
    featid2->SetDataType (FdoDataType_Int32);
    featid2->SetIsAutoGenerated (true);
    featid2->SetNullable (false);

    FdoPtr<FdoDataPropertyDefinition> id2 = FdoDataPropertyDefinition::Create (L"Id", L"integer");
    id2->SetDataType (FdoDataType_Decimal);
    id2->SetPrecision(10);
    id2->SetScale(0);

    FdoPtr<FdoDataPropertyDefinition> street2 = FdoDataPropertyDefinition::Create (L"Street", L"text");
    street2->SetDataType (FdoDataType_String);
    street2->SetLength (64);

    FdoPtr<FdoDataPropertyDefinition> area2 = FdoDataPropertyDefinition::Create (L"Area", L"decimal");
    area2->SetDataType (FdoDataType_Decimal);
    area2->SetPrecision(20);
    area2->SetScale(8);

    FdoPtr<FdoDataPropertyDefinition> vacant2 = FdoDataPropertyDefinition::Create (L"Vacant", L"boolean");
    vacant->SetDataType (FdoDataType_Boolean);

    FdoPtr<FdoDataPropertyDefinition> birthday2 = FdoDataPropertyDefinition::Create (L"Birthday", L"date");
    birthday2->SetDataType (FdoDataType_DateTime);

    // build a location geometry property
    FdoPtr<FdoGeometricPropertyDefinition> location2;
    if (type > 0)
    {
        location2 = FdoGeometricPropertyDefinition::Create (L"Geometry", L"geometry");
        location2->SetGeometryTypes (type);
        location2->SetHasElevation (elevation);
        location2->SetHasMeasure (measure);
    }

    properties2->Add (featid2);
    identities2->Add (featid2);
    properties2->Add (id2);
    properties2->Add (street2);
    properties2->Add (area2);
    properties2->Add (vacant2);
    properties2->Add (birthday2);
    if (type > 0)
    {
        properties2->Add (location2);
        feature2->SetGeometryProperty (location2);
    }


    // Create the FdoClass "TestFdoClass":
    //////////////////////////////////////////////////////////////////////////////////////////////////

    featid = FdoDataPropertyDefinition::Create (L"FeatId", L"integer");
    featid->SetDataType (FdoDataType_Int32);
    featid->SetIsAutoGenerated (true);
    featid->SetNullable (false);

    id = FdoDataPropertyDefinition::Create (L"Id", L"integer");
    id->SetDataType (FdoDataType_Decimal);
    id->SetPrecision(10);
    id->SetScale(0);

    street = FdoDataPropertyDefinition::Create (L"Street", L"text");
    street->SetDataType (FdoDataType_String);
    street->SetLength (64);

    area = FdoDataPropertyDefinition::Create (L"Area", L"decimal");
    area->SetDataType (FdoDataType_Decimal);
    area->SetPrecision(20);
    area->SetScale(8);

    vacant = FdoDataPropertyDefinition::Create (L"Vacant", L"boolean");
    vacant->SetDataType (FdoDataType_Boolean);

    birthday = FdoDataPropertyDefinition::Create (L"Birthday", L"date");
    birthday->SetDataType (FdoDataType_DateTime);

    //// assemble the feature class
    FdoPtr<FdoClass> fdoclass1 = FdoClass::Create (L"TestFdoClass", L"test class created with apply schema");
    properties = fdoclass1->GetProperties ();
    identities = fdoclass1->GetIdentityProperties ();
    properties->Add (featid);
    identities->Add (featid);
    properties->Add (id);
    properties->Add (street);
    properties->Add (area);
    properties->Add (vacant);
    properties->Add (birthday);


    // Create the new schema:
    //////////////////////////////////////////////////////////////////////////////////////////////////

    FdoPtr<FdoFeatureSchema> schema = FdoFeatureSchema::Create (schemaName, L"test schema");
    FdoPtr<FdoClassCollection> classes = schema->GetClasses ();
    classes->Add (feature);
    classes->Add (feature2);
    classes->Add (fdoclass1);

    FdoPtr<FdoIApplySchema> apply = (FdoIApplySchema*)mConnection->CreateCommand (FdoCommandType_ApplySchema);
    apply->SetFeatureSchema (schema);
    apply->Execute ();
    SaveSchema(mConnection);
}

void InsertTests::wide2multibyte(char *mb, wchar_t *in, int cpgWin, char *cpgLinux)
{        
    // This is a macro!
#ifdef _WIN32
    wide_to_multibyte_cpg(mb,in,cpgWin);
#else
    wide_to_multibyte_cpg(mb,in,cpgLinux);
#endif
}


void InsertTests::wide2mbPerformaceTest()
{
    try
    {
    int N=100000;
    wchar_t in[] = L"\x30F3\x30C6\x30F3\x30C4\x304C\x3042\x308B\x30C7\x30A3\x30EC\x30AF\x30C8\x30EA";

    char    out[200];
    size_t  outsize = 200;

    /////////////// Test setlocale() //////////////////////////

    clock_t start = clock();
    for (int i=0; i < N; i++)
    {
        char save[50];

        char *locale =setlocale(LC_CTYPE, "");
        strcpy(save, locale);
#ifdef _WIN32    
        setlocale(LC_CTYPE, ".51932");
#else
         setlocale(LC_CTYPE, "ja_JP.eucjp");
#endif                                                                                                                          
        wcstombs(out, in, outsize);

        setlocale(LC_CTYPE, save);
    }

    clock_t end = clock();
    double  passed =  (double)(end-start)/CLOCKS_PER_SEC;
    if (VERBOSE) printf("passed wcstombs: %lf (%lf per sec)\n", passed, passed/N);

    /////////////// Wide_to_multibyte_cpg() //////////////////////////
    start = clock();
    for (int i=0; i < N; i++)
    {
        char *mb=NULL;
#ifdef _WIN32
        wide2multibyte(mb,in, 932, NULL);
#else
        wide2multibyte(mb,in, -1, "EUC-JP");
#endif
    }

    end = clock();
    passed =  (double)(end-start)/CLOCKS_PER_SEC;
    if (VERBOSE) printf("passed w2m_cpg: %lf (%lf per sec)\n", passed, passed/N);
    
    /////////////// Test native conversion with codepage
    start = clock();
#ifdef _WIN32
    // Test WideCharToMultiByte() 
    const wchar_t* p = (in);
    size_t s = wcslen (p);
    s++;
    char *mb = (char*)malloc (s * 6);

    for (int i=0; i < N; i++)
    {
        int k = WideCharToMultiByte (
            932, // Japanese
            0,
            p,
            (int)s,
            mb,
            (int)s * 6,
            NULL,
            NULL);
    }
    delete[] mb;
    
    end = clock();
    passed =  (double)(end-start)/CLOCKS_PER_SEC;
    if (VERBOSE) printf("passed WideCharToMultiByte(): %lf (%lf per sec)\n", passed, passed/N);

#else
    /// Test iconv() 
    for (int i=0; i < N; i++)
    {
        iconv_t cd = iconv_open( "EUC-JP", "WCHAR_T"); 
    
        if (cd == (iconv_t)-1)
            CPPUNIT_FAIL ("iconv_open() failed");
    
        size_t  insize = (wcslen(in) + 1)* sizeof(wchar_t);
        size_t  insize2 = insize;
        char  *w = (char *)in;
        char  *mb = (char *)out;
        size_t outsize2 = outsize;
        
        size_t s = iconv(cd, (char**)&w, &insize2, (char**)&mb,
        &outsize2 ); 
        
        iconv_close(cd);

        if (s == (size_t)-1)
            CPPUNIT_FAIL ("iconv() failed");            
    }

    end = clock();
    passed =  (double)(end-start)/CLOCKS_PER_SEC;
    printf("passed iconv: %lf (%lf per sec)\n", passed, passed/N);

#endif
   }
   catch (FdoException* ge) 
   {
           TestCommonFail (ge);
   }
}

void InsertTests::insert ()
{
   try
   {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType(L"24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            // add NULL geometry value:
            FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
            geometry->SetNullValue ();
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            CPPUNIT_ASSERT_MESSAGE("featid should be 1-based", featid==1);


            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street nullness", !reader->IsNull (L"Street"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                
                // MapInfo Does not support NULL;
                //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                
                // MapInfo Does not support NULL;
                //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"GEOMETRY"));
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xy ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            // add real geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XY ( 9.99 18.56 )')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                //MapInfo Doesn't support NULL value
                //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoIPoint * pGeomB = (FdoIPoint*)gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoIPoint * pGeomA = (FdoIPoint*)gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::PointsEqual(pGeomB, pGeomA));

                //for (int i = 0; i < count; i++)
                //{
                //    FdoByte left = before->GetData ()[i];
                //    FdoByte right = after->GetData ()[i];
                //    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                //}
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FID"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                //MapInfo Doesn't support NULL value
                //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoIPoint * pGeomB = (FdoIPoint*)gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoIPoint * pGeomA = (FdoIPoint*)gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::PointsEqual(pGeomB, pGeomA));
                //for (int i = 0; i < count; i++)
                //{
                //    FdoByte left = before->GetData ()[i];
                //    FdoByte right = after->GetData ()[i];
                //    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                //}
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xyz ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, true, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"98.3", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-21'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XYZ ( 7171.723 8282.99 65.87)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xym ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, false, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"-24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'O''Connor Avenue'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"-8e6", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-10-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with measure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XYM ( 7171.723 8282.99 65.87)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xyzm ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"00024", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'O\"Connor Avenue'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"8.82828e12", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation and mesaure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XYZM ( 7171.723 8282.99 6824.82 65.87)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xy ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            // add real geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XY (999000 999000, 929200 928929, 923932 949494)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int count = before->GetCount ();
                int test = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", count == test);
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoIMultiPoint * pGeomB = (FdoIMultiPoint*)gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoIMultiPoint * pGeomA = (FdoIMultiPoint*)gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::MultiPointsEqual(pGeomB, pGeomA));
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (DEFAULT_GEOMETRY_PROPERTY_NAME));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (DEFAULT_GEOMETRY_PROPERTY_NAME);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoIMultiPoint * pGeomB = (FdoIMultiPoint*)gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoIMultiPoint * pGeomA = (FdoIMultiPoint*)gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::MultiPointsEqual(pGeomB, pGeomA));
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xyz ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, true, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);
        
            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"98.3", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-21'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XYZ (7171.723 8282.99 65.87, 7221.62 8737.82 69.828, 7828.23 8729.25 65.98)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xym ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, false, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"-24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'O''Connor Avenue'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"-8e6", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-10-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with measure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XYM (7171.723 8282.99 65.87, 7272.82 7987.72 75.76, 7626.82 8925.73 84.89)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xyzm ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"00024", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'O\"Connor Avenue'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"8.82828e12", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation and mesaure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XYZM (7171.723 8282.99 6824.82 65.87, 9929.82 4567.92 8921.88 69.28, 10010.7 9992.929 6278.92 87.90))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xy ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create (INT_MAX);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'~!@#$%^&*()'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"-8.8282e11", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-2'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MAX == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"~!@#$%^&*()", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8.8282e11 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MAX == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"~!@#$%^&*()", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8.8282e11 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xyz ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, true, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create (INT_MIN / 10);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'0123456789012345678901234567890123456789012345678901234567890123'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (/*-fNO_DATA*/ 1E38 - 1e-6);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-12-2'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XYZ ( 7171.723 8282.99 52.990, 6824.82 6545.87 57.712, 8920.5 9929.77 62.882)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MIN / 10 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"0123456789012345678901234567890123456789012345678901234567890123", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (1E38 - 1e-6) == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MIN / 10 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"0123456789012345678901234567890123456789012345678901234567890123", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (1E38 - 1e-6) == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xym ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"00000", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'2611 Misener Crescent'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (/*fNO_DATA*/ -1E38 + 1e-6);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"TRUE");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1492-12-2'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with measure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XYM ( 7171.723 8282.99 52.990, 6824.82 6545.87 57.712, 8920.5 9929.77 62.882)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 0 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"2611 Misener Crescent", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (-1E38 + 1e-6) == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1492 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 0 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"2611 Misener Crescent", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (-1E38 + 1e-6) == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1492 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xyzm ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"100000", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'/<>?.,\"'';:\\|][}{=-'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (-4);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"FALSE");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2048-12-31'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation and measure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XYZM ( 7171.723 8282.99 52.990 9, 6824.82 6545.87 57.712 8, 8920.5 9929.77 62.882 7)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 100000 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"/<>?.,\"';:\\|][}{=-", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -4 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2048 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 31 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 100000 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"/<>?.,\"';:\\|][}{=-", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -4 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2048 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 31 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xy ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((0 0, 0 5, 5 5, 5 0, 0 0), (1 1, 2 2, 3 1, 1 1))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::PolygonEqual(pGeomB, pGeomA));
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
             select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::PolygonEqual(pGeomB, pGeomA));
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xyz ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XYZ ((5108.8 5104.7 89.002, 5109 5104 93.828, 5109 5105 75.828, 5108.8 5104.7 89.002))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xym ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, false, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XYM ((5108.8 5104.7 89.002, 5109 5104 93.828, 5109 5105 75.828, 5108.8 5104.7 89.002))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xyzm ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value with elevation and measure:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XYZM ((5108.8 5104.7 5020.99 89.002, 5109.82 5104.82 5021.88 93.828, 5109.82 5105.61 5024.82 75.828, 5108.8 5104.7 5020.99 89.002))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xy ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XY ((5020.99 89.002, 5124.45 93.78, 5067.62 92.45), (5389.67 88.67, 5690.67 95.78, 5899.89 104.67, 5478.12 101.45))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::MultiLineStringEqual(pGeomB, pGeomA));
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::MultiLineStringEqual(pGeomB, pGeomA));
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xyz ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, true, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XYZ ((5020.99 89.002 1004.67, 5124.45 93.78 1289.72, 5067.62 92.45 1182.52), (5389.67 88.67 1156.32, 5690.67 95.78 1178.84, 5899.89 104.67 1172.72, 5478.12 101.45 1901.71))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xym ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XYM ((5020.99 89.002 1004.67, 5124.45 93.78 1289.72, 5067.62 92.45 1182.52), (5389.67 88.67 1156.32, 5690.67 95.78 1178.84, 5899.89 104.67 1172.72, 5478.12 101.45 1901.71))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xyzm ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XYZM ((5020.99 89.002 1004.67 6.934, 5124.45 93.78 1289.72 7.9192, 5067.62 92.45 1182.52 5.9292), (5389.67 88.67 1156.32 9.78278, 5690.67 95.78 1178.84 8.8383, 5899.89 104.67 1172.72 7.8282, 5478.12 101.45 1901.71 8.626))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xy ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XY (((5100 5230, 5100 5030, 5300 5030, 5300 5230, 5100 5230), (5239 5119, 5239 5141, 5261 5141, 5261 5119, 5239 5119), (5141 5135, 5141 5153, 5159 5153, 5159 5135, 5141 5135)), ((6100 5230, 6100 5030, 6300 5030, 6300 5230, 6100 5230), (6239 5119, 6239 5141, 6261 5141, 6261 5119, 6239 5119), (6141 5135, 6141 5153, 6159 5153, 6159 5135, 6141 5135)))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();

                FdoPtr<FdoGeometryValue> geometryAfter = FdoGeometryValue::Create(after);

                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::MultiPolygonEqual(pGeomB, pGeomA));
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::MultiPolygonEqual(pGeomB, pGeomA));
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xyz ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XYZ (((5100 5230 21.828, 5100 5030 22.2828, 5300 5030 20.28282, 5300 5230 21.28282, 5100 5230 21.828), (5239 5119 20, 5239 5141 20, 5261 5141 20, 5261 5119 20, 5239 5119 20), (5141 5135 20, 5141 5153 20, 5159 5153 20, 5159 5135 20, 5141 5135 20)), ((6100 5230 20, 6100 5030 20, 6300 5030 20, 6300 5230 20, 6100 5230 20), (6239 5119 20, 6239 5141 20, 6261 5141 20, 6261 5119 20, 6239 5119 20), (6141 5135 20, 6141 5153 20, 6159 5153 20, 6159 5135 20, 6141 5135 20)))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();

                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();

                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xym ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, false, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XYM (((5100 5230 1, 5100 5030 2, 5300 5030 3, 5300 5230 1, 5100 5230 1), (5239 5119 1, 5239 5141 2, 5261 5141 3, 5261 5119 1, 5239 5119 1), (5141 5135 1, 5141 5153 2, 5159 5153 3, 5159 5135 1, 5141 5135 1)), ((6100 5230 1, 6100 5030 2, 6300 5030 3, 6300 5230 1, 6100 5230 1), (6239 5119 1, 6239 5141 2, 6261 5141 3, 6261 5119 1, 6239 5119 1), (6141 5135 1, 6141 5153 2, 6159 5153 3, 6159 5135 1, 6141 5135 1)))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xyzm ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = FdoDecimalValue::Create (99.9999);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XYZM (((5100 5230 20 1, 5100 5030 20 2, 5300 5030 20 3, 5300 5230 20 1, 5100 5230 20 1), (5239 5119 20 1, 5239 5141 20 2, 5261 5141 20 3, 5261 5119 20 1, 5239 5119 20 1), (5141 5135 20 1, 5141 5153 20 2, 5159 5153 20 3, 5159 5135 20 1, 5141 5135 20 1)), ((6100 5230 20 1, 6100 5030 20 2, 6300 5030 20 3, 6300 5230 20 1, 6100 5230 20 1), (6239 5119 20 1, 6239 5141 20 2, 6261 5141 20 3, 6261 5119 20 1, 6239 5119 20 1), (6141 5135 20 1, 6141 5153 20 2, 6159 5153 20 3, 6159 5135 20 1, 6141 5135 20 1)))')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_curvestring()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();

            FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
            FdoPtr<FdoCurveSegmentCollection> curveSegments = FdoCurveSegmentCollection::Create();
            FdoPtr<FdoIDirectPosition> pos1 = gf->CreatePositionXY(0.0, 0.0);
            FdoPtr<FdoIDirectPosition> pos2 = gf->CreatePositionXY(1.0, 1.0);
            FdoPtr<FdoIDirectPosition> pos3 = gf->CreatePositionXY(2.0, 0.0);
            FdoPtr<FdoICircularArcSegment> arcSegment1 = gf->CreateCircularArcSegment(pos1, pos2, pos3);
            curveSegments->Add(arcSegment1);
            FdoPtr<FdoICurveString> curveString = (FdoICurveString*)gf->CreateCurveString( curveSegments );
            FdoPtr<FdoByteArray> byteArray = gf->GetFgf(curveString);
            FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create(byteArray);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            try
            {
                FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
                TestCommonFail ("An exception is expected here because MapInfo doesn't support those geometry types.");
            }
            catch(FdoException* e)
            {
                FdoStringP errMsg = e->GetExceptionMessage();
                CPPUNIT_ASSERT_MESSAGE ("Incorrect error message!", errMsg.Contains(L"Geometry type 'CurveString' is not supported by MapInfo provider."));
            }
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_curvepolygon()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();

            // add a curvepolygon with 2 circular arc segments:
            FdoPtr<FdoCurveSegmentCollection> curveSegments = FdoCurveSegmentCollection::Create();
            FdoPtr<FdoIDirectPosition> pos1 = gf->CreatePositionXY(0.0, 0.0);
            FdoPtr<FdoIDirectPosition> pos2 = gf->CreatePositionXY(1.0, 1.0);
            FdoPtr<FdoIDirectPosition> pos3 = gf->CreatePositionXY(2.0, 0.0);
            FdoPtr<FdoICircularArcSegment> arcSegment1 = gf->CreateCircularArcSegment(pos1, pos2, pos3);
            curveSegments->Add(arcSegment1);
            FdoPtr<FdoIDirectPosition> pos4 = gf->CreatePositionXY(2.0, 0.0);
            FdoPtr<FdoIDirectPosition> pos5 = gf->CreatePositionXY(1.0, -1.0);
            FdoPtr<FdoIDirectPosition> pos6 = gf->CreatePositionXY(0.0, 0.0);
            FdoPtr<FdoICircularArcSegment> arcSegment2 = gf->CreateCircularArcSegment(pos4, pos5, pos6);
            curveSegments->Add(arcSegment2);
            FdoPtr<FdoIRing> ring = (FdoIRing*)gf->CreateRing( curveSegments );
            FdoPtr<FdoICurvePolygon> curvePoly = gf->CreateCurvePolygon(ring, NULL);
            FdoPtr<FdoByteArray> byteArray = gf->GetFgf(curvePoly);
            FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create(byteArray);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            try
            {
                FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
                TestCommonFail ("An exception is expected here because MapInfo doesn't support those geometry types.");
            }
            catch(FdoException* e)
            {
                FdoStringP errMsg = e->GetExceptionMessage();
                CPPUNIT_ASSERT_MESSAGE ("Incorrect error message!", errMsg.Contains(L"Geometry type 'CurvePolygon' is not supported by MapInfo provider."));
            }
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multicurvestring()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();

            FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
            FdoPtr<FdoCurveSegmentCollection> curveSegments = FdoCurveSegmentCollection::Create();
            FdoPtr<FdoIDirectPosition> pos1 = gf->CreatePositionXY(0.0, 0.0);
            FdoPtr<FdoIDirectPosition> pos2 = gf->CreatePositionXY(1.0, 1.0);
            FdoPtr<FdoIDirectPosition> pos3 = gf->CreatePositionXY(2.0, 0.0);
            FdoPtr<FdoICircularArcSegment> arcSegment1 = gf->CreateCircularArcSegment(pos1, pos2, pos3);
            curveSegments->Add(arcSegment1);
            FdoPtr<FdoICurveString> curveString = (FdoICurveString*)gf->CreateCurveString( curveSegments );
            FdoPtr<FdoCurveStringCollection> curveCollection = FdoCurveStringCollection::Create();
            curveCollection->Add(curveString);
            FdoPtr<FdoIMultiCurveString> multiCurveString = (FdoIMultiCurveString*)gf->CreateMultiCurveString(curveCollection);
            FdoPtr<FdoByteArray> byteArray = gf->GetFgf(multiCurveString);
            FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create(byteArray);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            try
            {
                FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
                TestCommonFail ("An exception is expected here because MapInfo doesn't support those geometry types.");
            }
            catch(FdoException* e)
            {
                FdoStringP errMsg = e->GetExceptionMessage();
                CPPUNIT_ASSERT_MESSAGE ("Incorrect error message!", errMsg.Contains(L"Geometry type 'MultiCurveString' is not supported by MapInfo provider."));
            }
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multicurvepolygon()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();

            // add a curvepolygon with 2 circular arc segments:
            FdoPtr<FdoCurveSegmentCollection> curveSegments = FdoCurveSegmentCollection::Create();
            FdoPtr<FdoIDirectPosition> pos1 = gf->CreatePositionXY(0.0, 0.0);
            FdoPtr<FdoIDirectPosition> pos2 = gf->CreatePositionXY(1.0, 1.0);
            FdoPtr<FdoIDirectPosition> pos3 = gf->CreatePositionXY(2.0, 0.0);
            FdoPtr<FdoICircularArcSegment> arcSegment1 = gf->CreateCircularArcSegment(pos1, pos2, pos3);
            curveSegments->Add(arcSegment1);
            FdoPtr<FdoIDirectPosition> pos4 = gf->CreatePositionXY(2.0, 0.0);
            FdoPtr<FdoIDirectPosition> pos5 = gf->CreatePositionXY(1.0, -1.0);
            FdoPtr<FdoIDirectPosition> pos6 = gf->CreatePositionXY(0.0, 0.0);
            FdoPtr<FdoICircularArcSegment> arcSegment2 = gf->CreateCircularArcSegment(pos4, pos5, pos6);
            curveSegments->Add(arcSegment2);
            FdoPtr<FdoIRing> ring = (FdoIRing*)gf->CreateRing( curveSegments );
            FdoPtr<FdoICurvePolygon> curvePolygon = gf->CreateCurvePolygon(ring, NULL);
            FdoPtr<FdoCurvePolygonCollection> curvePolygonCollection = FdoCurvePolygonCollection::Create();
            curvePolygonCollection->Add(curvePolygon);
            FdoPtr<FdoIMultiCurvePolygon> multiCurvePolygon = gf->CreateMultiCurvePolygon(curvePolygonCollection);
            FdoPtr<FdoByteArray> byteArray = gf->GetFgf(multiCurvePolygon);
            FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create(byteArray);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);

            try
            {
                FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
                TestCommonFail ("An exception is expected here because MapInfo doesn't support those geometry types.");
            }
            catch(FdoException* e)
            {
                FdoStringP errMsg = e->GetExceptionMessage();
                CPPUNIT_ASSERT_MESSAGE ("Incorrect error message!", errMsg.Contains(L"Geometry type 'MultiCurvePolygon' is not supported by MapInfo provider."));
            }
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_invalid_polygons()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Surface, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression;
            FdoPtr<FdoPropertyValue> value;

            // Add geometry value that contains multiple invalid loops;
            // Obsolete: such polygons need to roundtrip without errors/modification according to ECO 10400:
            // Actual: according to RFC 38 the type of the output geometry is not guarranteed. In this case
            // a multi-polygon should be returned instead.
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (
                L"GeomFromText('POLYGON XYZM ("
                L"(1100 1100 20 1, 1200 1100 20 2, 1200 1200 20 3, 1100 1200 20 1, 1100 1100 20 1),"  // inner ring as first ring
                L"(1000 1000 20 1, 2000 1000 20 2, 2000 2000 20 3, 1000 2000 20 1, 1000 1000 20 1),"  // outer ring as second ring
                L"(1000 1000 20 1, 1000 1000 20 2, 1000 1000 20 3, 1000 1000 20 1, 1000 1000 20 1),"  // degenerate ring (all points equal)
                L"(3000 3000 20 1, 4000 4000 20 2, 3000 4000 20 3, 4000 3000 20 1, 3000 3000 20 1),"  // self-intersecting ring
                L"(1000 1000 20 1, 1000 2000 20 1, 2000 2000 20 3, 2000 1000 20 2, 1000 1000 20 1)"   // opposite vertex order compared to scond ring, and fully overlapping
                L")')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();

                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b != a);
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();

                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b != a);
             }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}


/* Batch insert tests */
void InsertTests::batch_insert ()
{
    try
    {
        for (FdoInt32 k = 0; k < m_schemaNames->GetCount(); ++k)
        {
            create_schema (m_schemaNames->GetString(k), FdoGeometricType_Curve, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(k), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();

            // Set up the property value collection:
            FdoPtr<FdoPropertyValue> value;
            FdoPtr<FdoLiteralValue> expression;
            FdoPtr<FdoParameter>  parameter;

            parameter = FdoParameter::Create (L"Param0");
            value = FdoPropertyValue::Create (L"Id", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param1");
            value = FdoPropertyValue::Create (L"Street", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param2");
            value = FdoPropertyValue::Create (L"Area", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param3");
            value = FdoPropertyValue::Create (L"Vacant", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param4");
            value = FdoPropertyValue::Create (L"Birthday", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param5");
            value = FdoPropertyValue::Create (L"Geometry", parameter);
            values->Add (value);

            // fill the batch parameter value collection with multiple (2) rows of data
            FdoPtr<FdoBatchParameterValueCollection> parameters = insert->GetBatchParameterValues ();
            FdoPtr<FdoParameterValue> parameterValue;

            // row 1
            FdoPtr<FdoParameterValueCollection> collection = FdoParameterValueCollection::Create ();
            FdoPtr<FdoLiteralValue> valueExpression = (FdoLiteralValue*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'4 Linux Loop'");
            parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
            collection->Add (parameterValue);
            valueExpression = FdoDecimalValue::Create (256.00);
            parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"true");
            parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-18'");
            parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
            collection->Add (parameterValue);
            FdoPtr<FdoGeometryValue> geometry1 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
            parameterValue = FdoParameterValue::Create (L"Param5", geometry1);
            collection->Add (parameterValue);
            parameters->Add (collection);

            // row 2
            collection = FdoParameterValueCollection::Create ();
            valueExpression = (FdoLiteralValue*)MapInfoTests::ParseByDataType (L"11", FdoDataType_Decimal);
            parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'84 Windows Way'");
            parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
            collection->Add (parameterValue);
            valueExpression = FdoDecimalValue::Create (128.00);
            parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"false");
            parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-16'");
            parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
            collection->Add (parameterValue);
            FdoPtr<FdoGeometryValue> geometry2 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 6677.99 7820.89, 6272.90 7020.20, 7012.82 7516.91)')");
            parameterValue = FdoParameterValue::Create (L"Param5", geometry2);
            collection->Add (parameterValue);
            parameters->Add (collection);

            // perform the batch insert
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

            // check the id's
            FdoInt32 featid1;
            FdoInt32 featid2;
            featid1 = -1;
            featid2 = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid1)
                    if (-1 != featid2)
                        CPPUNIT_FAIL ("too many features inserted");
                    else
                        featid2 = reader->GetInt32 (L"FeatId");
                else
                    featid1 = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid2)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            selectCmd->SetFeatureClassName (qualifiedFeatureClassName);
            reader = selectCmd->Execute ();
            while (reader->ReadNext ())
            {
                if (featid1 == reader->GetInt32 (L"FeatId"))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                    FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
                else if (featid2 == reader->GetInt32 (L"FeatId"))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                    FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            selectCmd->SetFeatureClassName (qualifiedFeatureClassName);
            reader = selectCmd->Execute ();
            while (reader->ReadNext ())
            {
                if (featid1 == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (DEFAULT_GEOMETRY_PROPERTY_NAME));
                    FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (DEFAULT_GEOMETRY_PROPERTY_NAME);
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
                else if (featid2 == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (DEFAULT_GEOMETRY_PROPERTY_NAME));
                    FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (DEFAULT_GEOMETRY_PROPERTY_NAME);
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

/* null insert tests */
void InsertTests::null_geometry_insert ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();

            // Set up the property value collection:
            FdoPtr<FdoPropertyValue> value;
            FdoPtr<FdoLiteralValue> expression;
            FdoPtr<FdoParameter>  parameter;

            parameter = FdoParameter::Create (L"Param0");
            value = FdoPropertyValue::Create (L"Id", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param1");
            value = FdoPropertyValue::Create (L"Street", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param2");
            value = FdoPropertyValue::Create (L"Area", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param3");
            value = FdoPropertyValue::Create (L"Vacant", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param4");
            value = FdoPropertyValue::Create (L"Birthday", parameter);
            values->Add (value);

            parameter = FdoParameter::Create (L"Param5");
            value = FdoPropertyValue::Create (L"Geometry", parameter);
            values->Add (value);

            // fill the batch parameter value collection with multiple (3) rows of data,
            // one of which has a null geometry
            FdoPtr<FdoBatchParameterValueCollection> parameters = insert->GetBatchParameterValues ();
            FdoPtr<FdoParameterValue> parameterValue;

            // row 1
            FdoPtr<FdoParameterValueCollection> collection = FdoParameterValueCollection::Create ();
            FdoPtr<FdoLiteralValue> valueExpression = (FdoLiteralValue*)MapInfoTests::ParseByDataType (L"7", FdoDataType_Decimal);
            parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'4 Linux Loop'");
            parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
            collection->Add (parameterValue);
            valueExpression = FdoDecimalValue::Create (256.00);
            parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"true");
            parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-18'");
            parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
            collection->Add (parameterValue);
            FdoPtr<FdoGeometryValue> geometry1 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
            parameterValue = FdoParameterValue::Create (L"Param5", geometry1);
            collection->Add (parameterValue);
            parameters->Add (collection);

            // row 2
            collection = FdoParameterValueCollection::Create ();
            valueExpression = (FdoLiteralValue*)MapInfoTests::ParseByDataType (L"11", FdoDataType_Decimal);
            parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'84 Windows Way'");
            parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
            collection->Add (parameterValue);
            valueExpression = FdoDecimalValue::Create (128.00);
            parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"false");
            parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-16'");
            parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
            collection->Add (parameterValue);
            // insert a NULL geometry
            parameters->Add (collection);

            // row 3
            collection = FdoParameterValueCollection::Create ();
            valueExpression = (FdoLiteralValue*)MapInfoTests::ParseByDataType (L"11", FdoDataType_Decimal);
            parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'84 Windows Way'");
            parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
            collection->Add (parameterValue);
            valueExpression = FdoDecimalValue::Create (128.00);
            parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"false");
            parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
            collection->Add (parameterValue);
            valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-16'");
            parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
            collection->Add (parameterValue);
            FdoPtr<FdoGeometryValue> geometry2 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 6677.99 7820.89, 6272.90 7020.20, 7012.82 7516.91)')");
            parameterValue = FdoParameterValue::Create (L"Param5", geometry2);
            collection->Add (parameterValue);
            parameters->Add (collection);

            // perform the batch insert
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

            // check the id's
            FdoInt32 featid1;
            FdoInt32 featid2;
            FdoInt32 featid3;
            featid1 = -1;
            featid2 = -1;
            featid3 = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid1)
                    if (-1 != featid2)
                        if (-1 != featid3)
                            CPPUNIT_FAIL ("too many features inserted");
                        else
                            featid3 = reader->GetInt32 (L"FeatId");
                    else
                        featid2 = reader->GetInt32 (L"FeatId");
                else
                    featid1 = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid3)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            selectCmd->SetFeatureClassName (qualifiedFeatureClassName);
            reader = selectCmd->Execute ();
            while (reader->ReadNext ())
            {
                if (featid1 == reader->GetInt32 (L"FeatId"))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                    FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
                else if (featid2 == reader->GetInt32 (L"FeatId"))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is not null", reader->IsNull (L"Geometry"));
                }
                else if (featid3 == reader->GetInt32 (L"FeatId"))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                    FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            selectCmd->SetFeatureClassName (qualifiedFeatureClassName);
            reader = selectCmd->Execute ();
            while (reader->ReadNext ())
            {
                if (featid1 == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (DEFAULT_GEOMETRY_PROPERTY_NAME));
                    FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (DEFAULT_GEOMETRY_PROPERTY_NAME);
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
                else if (featid2 == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is not null", reader->IsNull (DEFAULT_GEOMETRY_PROPERTY_NAME));
                }
                else if (featid3 == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME))
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (DEFAULT_GEOMETRY_PROPERTY_NAME));
                    FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (DEFAULT_GEOMETRY_PROPERTY_NAME);
                    int b = before->GetCount ();
                    int a = after->GetCount ();
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);

                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), b);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), a);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::null_data_insert ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, true, true);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create();  //NULL
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = FdoStringValue::Create(); // NULL
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            // add NULL geometry value:
            FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
            geometry->SetNullValue ();
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;
            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (qualifiedFeatureClassName);
            reader = select->Execute ();
            while (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", reader->IsNull (L"Id"));             // explicitly inserted NULL
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", reader->IsNull(L"Street"));      // explicitly inserted NULL
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));         // implicitly inserted NULL
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));     // implicitly inserted NULL
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday")); // implicitly inserted NULL
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry")); // explicitly inserted NULL
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}



void InsertTests::insert_large_first_geometry ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);
            for (int ii=0; ii<1; ii++)  // can add mroe iterations if desired, but it doesnt seem to help reproduce the problem
            {
                create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, false);

                FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
                insert->SetFeatureClassName (qualifiedFeatureClassName);
                FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
                FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"24", FdoDataType_Decimal);
                FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
                values->Add (value);
                expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
                value = FdoPropertyValue::Create (L"Street", expression);
                values->Add (value);
                // add real geometry value (that is over 5k, so to exceed the buffer size minimum of 5k):
                FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ("
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                    L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0"
                    L")')");
                value = FdoPropertyValue::Create (L"Geometry", geometry);
                values->Add (value);
                FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
                FdoInt32 featid;
                featid = -1;

                while (reader->ReadNext ())
                {
                    if (-1 != featid)
                        CPPUNIT_FAIL ("too many features inserted");
                    featid = reader->GetInt32 (L"FeatId");
                }
                reader->Close ();
                if (-1 == featid)
                    CPPUNIT_FAIL ("too few features inserted");

                // Insert the same large geometry a few more times:
                reader = insert->Execute ();
                reader->Close();
                reader = insert->Execute ();
                reader->Close();
                reader = insert->Execute ();
                reader->Close();


                // check by doing a select
                FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
                select->SetFeatureClassName (qualifiedFeatureClassName);
                reader = select->Execute ();
                if (reader->ReadNext ())
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                    //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                    //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                    //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                    FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                    int count = before->GetCount ();
                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
                reader->Close ();

                // close and reopen the connection
                mConnection->Close ();
                CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

                // check by doing a select
                select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
                select->SetFeatureClassName (qualifiedFeatureClassName);
                reader = select->Execute ();
                if (reader->ReadNext ())
                {
                    CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (DEFAULT_FEATURE_ID_PROPERTY_NAME));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                    CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                    //CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                    //CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                    //CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                    CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                    FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                    FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                    int count = before->GetCount ();
                    FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
                    FdoPtr<FdoIGeometry> pGeomB = gf->CreateGeometryFromFgf(before->GetData(), count);
                    FdoPtr<FdoIGeometry> pGeomA = gf->CreateGeometryFromFgf(after->GetData(), count);
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", UnitTestUtil::LineEqual(pGeomB, pGeomA));
                }
                reader->Close ();
            }
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}



void InsertTests::TestGeometrylessClass(FdoString* schemaName, FdoString* className, FdoClassType classType)
{
    FdoStringP classQName = FdoStringP::Format(L"%ls:%ls", schemaName, className);

    // Insert some data:
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
    insert->SetFeatureClassName (classQName);
    FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
    FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType(L"24", FdoDataType_Decimal);
    FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
    values->Add (value);
    expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
    value = FdoPropertyValue::Create (L"Street", expression);
    values->Add (value);
    FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
    FdoInt32 featid;
    featid = -1;
    while (reader->ReadNext ())
    {
        if (-1 != featid)
            CPPUNIT_FAIL ("too many features inserted");
        featid = reader->GetInt32 (L"FeatId");
    }
    reader->Close ();
    if (-1 == featid)
        CPPUNIT_FAIL ("too few features inserted");


    // Update some data:
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoIUpdate> update = (FdoIUpdate*)mConnection->CreateCommand (FdoCommandType_Update);
    update->SetFeatureClassName (classQName);
    values = update->GetPropertyValues ();
    expression = (FdoValueExpression*)FdoExpression::Parse (L"'123 Smithereen Lane'");
    value = FdoPropertyValue::Create (L"Street", expression);
    values->Add (value);
    FdoInt32 updatedRowCount = update->Execute ();


    // Check by doing a select:
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
    select->SetFeatureClassName (classQName);
    reader = select->Execute ();
    while (reader->ReadNext ())
    {
        CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect street nullness", !reader->IsNull (L"Street"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"123 Smithereen Lane", reader->GetString (L"Street")));
        CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));

        try
        {
            bool bDummy = reader->IsNull (L"Geometry");
            CPPUNIT_FAIL("Geometry property was found, but should not exist");
        }
        catch (FdoException *e)
        {
            e->Release();
        }
    }
    reader->Close ();


    // close and reopen the connection
    ///////////////////////////////////////////////////////////////////////

    mConnection->Close ();
    CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());


    // Do a DescribeSchema to ensure there is no geometry property
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoIDescribeSchema> descSchema = (FdoIDescribeSchema*)mConnection->CreateCommand(FdoCommandType_DescribeSchema);
    FdoPtr<FdoFeatureSchemaCollection> schemas = descSchema->Execute();
    FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(schemaName);
    FdoPtr<FdoClassCollection> classes = schema->GetClasses();
    FdoPtr<FdoClassDefinition> classDef = classes->GetItem(className);
    CPPUNIT_ASSERT_MESSAGE("Wrong class type", classDef->GetClassType() == classType);
    if (classType == FdoClassType_FeatureClass)
    {
        FdoFeatureClass* featureClass = (FdoFeatureClass*)classDef.p;
        FdoPtr<FdoGeometricPropertyDefinition> geomProp = featureClass->GetGeometryProperty();
        CPPUNIT_ASSERT_MESSAGE("Expected no geometry property", geomProp == NULL);
    }
    FdoPtr<FdoPropertyDefinitionCollection> props = classDef->GetProperties();
    for (int i=0; i<props->GetCount(); i++)
    {
        FdoPtr<FdoPropertyDefinition> prop = props->GetItem(i);
        CPPUNIT_ASSERT_MESSAGE("Expected no geometry properties", prop->GetPropertyType() != FdoPropertyType_GeometricProperty);
    }


    // check by doing a select
    ///////////////////////////////////////////////////////////////////////

    select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
    select->SetFeatureClassName (classQName);
    reader = select->Execute ();
    while (reader->ReadNext ())
    {
        CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"123 Smithereen Lane", reader->GetString (L"Street")));
        CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));

        try
        {
            bool bDummy = reader->IsNull (L"Geometry");
            CPPUNIT_FAIL("Geometry property was found, but should not exist");
        }
        catch (FdoException *e)
        {
            e->Release();
        }
    }
    reader->Close ();
    reader = NULL;
}


void InsertTests::insert_no_geometry ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            // Create shapefiles without geometry:
            create_schema (m_schemaNames->GetString(i), (FdoGeometricType)0, true, true);

            // Test FdoFeatureClass "Test":
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);
            TestGeometrylessClass(m_schemaNames->GetString(i), TEST_FEATURE_CLASS, FdoClassType_FeatureClass);

            // Test FdoClass "testFdoClass":
            qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TESTFDOCLASS_FEATURE_CLASS);
            TestGeometrylessClass(m_schemaNames->GetString(i), TEST_FEATURE_CLASS, FdoClassType_Class);
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_2connects ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Point, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            // Do Describe schema of 1st connection and Insert on second.
            FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)mConnection->CreateCommand (FdoCommandType_DescribeSchema);
            FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute ();

            // Do an insert on 2nd connection 
            FdoPtr<FdoIConnection>    pConnection2 = MapInfoTests::GetConnection ();
            pConnection2->SetConnectionString (L"DefaultFileLocation=" LOCATION);
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == pConnection2->Open ());

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            FdoPtr<FdoIInsert> insert2 = (FdoIInsert*)pConnection2->CreateCommand (FdoCommandType_Insert);

            // Insert on conn #2
            insert_connection( pConnection2, insert2, qualifiedFeatureClassName, L"200", DEFAULT_FEATURE_ID_PROPERTY_NAME);
            try 
            {
                // Trying to insert on conn #1 in the same class will fail since conn #1 has locked the fileset
                insert_connection( mConnection, insert, qualifiedFeatureClassName, L"100", L"FeatId");
                CPPUNIT_FAIL ("We expect one exception here.");
            }
            catch (FdoException* ge) 
            {
                ge->Release();
            }

            CPPUNIT_ASSERT_MESSAGE ("Wrong number of features in Test", get_count( pConnection2, qualifiedFeatureClassName )== 1); 
            pConnection2->Close();

            // Switch insert conn #1 to another class
            // This should be possible since conn #2 didn't lock the files.
            qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST2_FEATURE_CLASS);
            insert_connection( mConnection, insert, qualifiedFeatureClassName, L"100", L"FeatId");

            // Do one more insert
            insert_connection( mConnection, insert, qualifiedFeatureClassName, L"102", L"FeatId");

            CPPUNIT_ASSERT_MESSAGE ("Wrong number of features in Test2", get_count( mConnection, qualifiedFeatureClassName )== 2); 
        
            // Cleanup - it makes a difference if the insert is released before connection or the insert is properly freed.
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_2connects_flush ()
{
    try
    {
        for (FdoInt32 i = 0; i < m_schemaNames->GetCount(); ++i)
        {
            create_schema (m_schemaNames->GetString(i), FdoGeometricType_Curve, false, false);
            FdoStringP qualifiedFeatureClassName = GetQualifiedClassName(m_schemaNames->GetString(i), TEST_FEATURE_CLASS);

            // Do Describe schema of 1st connection and Insert on second.
            FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)mConnection->CreateCommand (FdoCommandType_DescribeSchema);
            FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute ();

            // Create 2 connections on the same fileset
            FdoPtr<FdoIConnection>    MapInfoSelect = MapInfoTests::GetConnection ();
            MapInfoSelect->SetConnectionString (L"DefaultFileLocation=" LOCATION);
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == MapInfoSelect->Open ());

            FdoPtr<FdoIConnection>    pConnection2 = MapInfoTests::GetConnection ();
            pConnection2->SetConnectionString (L"DefaultFileLocation=" LOCATION);
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == pConnection2->Open ());

            // Do an insert on 1st connection 
            FdoPtr<FdoIInsert> insert = (FdoIInsert*)pConnection2->CreateCommand (FdoCommandType_Insert);

            insert->SetFeatureClassName (qualifiedFeatureClassName);
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create (INT_MAX);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'~!@#$%^&*()'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (L"-8.8282e12", FdoDataType_Decimal);
            value = FdoPropertyValue::Create (L"Area", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
            value = FdoPropertyValue::Create (L"Vacant", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-2'");
            value = FdoPropertyValue::Create (L"Birthday", expression);
            values->Add (value);

            // add geometry value:
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

            CPPUNIT_ASSERT_MESSAGE ("Conn1: Wrong number of features in Test after flush", get_count( MapInfoSelect, qualifiedFeatureClassName )== 1); 

            //////////// Now the 2nd connection should see the updates on the same class
            MapInfoSelect->Flush();

            CPPUNIT_ASSERT_MESSAGE ("Conn2: Wrong number of features in Test", get_count( pConnection2, qualifiedFeatureClassName )== 1); 
        
            // Check the extents - This should suffice since it's just one geometry.
            FdoPtr<FdoISelectAggregates> advsel = (FdoISelectAggregates*)(pConnection2->CreateCommand(FdoCommandType_SelectAggregates));
            advsel->SetFeatureClassName(qualifiedFeatureClassName);
            
            FdoPtr<FdoIdentifierCollection> ids = advsel->GetPropertyNames();
            FdoPtr<FdoExpression> expr = FdoExpression::Parse(L"SpatialExtents(GEOMETRY)");
            FdoPtr<FdoComputedIdentifier> cid = FdoComputedIdentifier::Create(L"MBR", expr);
            ids->Add(cid);

            FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
            FdoPtr<FdoIDataReader> rdr = advsel->Execute();

            FdoPtr<FdoIEnvelope> extents;
            while (rdr->ReadNext())
            {
                if ( rdr->IsNull(L"MBR") )
                    CPPUNIT_FAIL("Expected not-null envelope for SpatialExtents() result");

                FdoPtr<FdoByteArray> geomBytes = rdr->GetGeometry(L"MBR");
                FdoPtr<FdoIGeometry> geom = gf->CreateGeometryFromFgf(geomBytes);

                FdoGeometryType geomType = geom->GetDerivedType();
                if (geomType != FdoGeometryType_Polygon)
                    CPPUNIT_FAIL("Expected Polygon geometry for SpatialExtents() result");

                extents = geom->GetEnvelope();
                if (extents->GetIsEmpty())
                    CPPUNIT_FAIL("Expected non-empty envelope for SpatialExtents() result");
            }

            MapInfoSelect->Close();
            pConnection2->Close();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

int InsertTests::get_count( FdoIConnection* connection, FdoString* class_name )
{
    FdoPtr<FdoISelect> select = (FdoISelect*)connection->CreateCommand (FdoCommandType_Select);
    select->SetFeatureClassName (class_name);
    FdoPtr<FdoIFeatureReader> reader = select->Execute ();

    int count = 0;
    while (reader->ReadNext ())
    {
        count++;
    }
    reader->Close ();

    return count;
}

void InsertTests::insert_connection( FdoIConnection* connection, FdoIInsert *insert2, FdoString* className, FdoString* id, FdoString* strFeatId )
{
    insert2->SetFeatureClassName (className);
    FdoPtr<FdoPropertyValueCollection> values = insert2->GetPropertyValues ();
    FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)MapInfoTests::ParseByDataType (id, FdoDataType_Decimal);
    FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
    values->Add (value);
    expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
    value = FdoPropertyValue::Create (L"Street", expression);
    values->Add (value);
    // add real geometry value:
    FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XY ( 9.99 18.56 )')");
    value = FdoPropertyValue::Create (L"Geometry", geometry);
    values->Add (value);
    FdoPtr<FdoIFeatureReader> reader = insert2->Execute ();

    FdoInt32 featid;
    featid = -1;
    while (reader->ReadNext ())
    {
        if (-1 != featid)
            CPPUNIT_FAIL ("too many features inserted");
        featid = reader->GetInt32 (strFeatId);
    }
    reader->Close ();
    if (-1 == featid)
        CPPUNIT_FAIL ("too few features inserted");
}
